<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>用户管理</title>
        <script src="/lib/axios.js"></script>
        <script src="/lib/vue.js"></script>
        <link rel="stylesheet" href="/lib/elementindex.css">
        <script src="/lib/elementindex.js"></script>
        <style>
            .el-aside {
/*                background-color: #D3DCE6;
                color: #333;
                text-align: center;
                line-height: 200px; */
              }
              
              .el-main {
/*                background-color: #E9EEF3;
                color: #333;
                text-align: center;
                line-height: 160px; */
              }
        </style>
    </head>
    <body>
        <div id='app'>
            <el-form label-width="auto">
                <el-container>
                    <el-aside width="320px">
                        <br />
                        <el-table ref='roletable' border :data="authdata.roleList" :current-row-key='currentRole.id'
                            style="width: 100%;margin-bottom: 20px;" row-key="id" @cell-dblclick='handleCellDblClick'
                            highlight-current-row @current-change='handleCurrentChange'>
                            <el-table-column label="角色" prop="code" sortable>
                                <template slot-scope="scope">
                                    <span style="color: gray;display:inline-flex;">{{scope.row.id}}.
                                        <el-input v-model.trim="scope.row.code" placeholder="角色名称" v-if="editing === 'code-'+scope.row.id"
                                            :ref="'code-'+scope.row.id" @blur="handleInputBlur('code-'+scope.row.id)"
                                            @keyup.enter.native="handleInputBlur('code-'+scope.row.id)">
                                        </el-input>
                                        <span v-else>{{scope.row.code}}</span></span>
                                </template>
                            </el-table-column>
                            <el-table-column title="操作" min-width="30px">
                                <template slot="header">
                                    <el-button type="success" size='mini' @click="handleAppend">(+)
                                    </el-button>
                                </template>
                                <template slot-scope="scope">
                                    <el-link plain type="danger" size='mini' @click="handleDelete(scope.$index)">X</el-link>&nbsp;
                                    <!-- <el-link type="primary" size='mini' @click="handleInsert(scope.$index)">干</el-link> -->
                                </template>
                            </el-table-column>
                        </el-table>
                    </el-aside>
                    <el-main>

                        <span class='el-card'><span>功能权限</span>
                            <el-checkbox :indeterminate="permitstatus['@func:*']" v-model="permit['@func:*']" label='全选'
                                :key='-1' @change="handleFuncPermitChecked('@func:*')"></el-checkbox>
                        </span>
                        <div>
                            <el-checkbox v-for='item in funcPermList' v-model="permit['@func:' + item.code]" :label='item.name'
                                :key='item.id' @change="handleFuncPermitChecked('@func:' + item.code)"></el-checkbox>
                        </div>
                        <span class='el-card'>规则权限</span>
                        <el-table ref='authtable' :indent="8" :data="projectTree" style="width: 100%;margin-bottom: 20px;"
                            row-key="rrid" border :tree-props="{children: 'list', hasChildren: 'hasChildren'}">
                            <el-table-column label="决策条件" min-width="80%" prop='rname'>
                            </el-table-column>

                            <el-table-column v-for="item in rulePermList" :key="item.id" min-width='22px'>
                                <template slot="header">
                                    <span>{{item.name}}</span>
                                </template>
                                <template slot-scope="scope">
                                    <!-- <span>{{scope.row.rrid +':' + item.code}}</span> -->
                                    <el-checkbox :indeterminate="permitstatus[scope.row.rrid +':' + item.code]" v-model="permit[scope.row.rrid +':' + item.code]"
                                        @change="handlePermitChecked(scope.row.rrid +':' + item.code)">授予</el-checkbox>
                                </template>
                            </el-table-column>
                        </el-table>
                    </el-main>
                </el-container>

                <el-form-item label="">
                    <el-button type="primary" @click='handleSave'>保存</el-button>
                </el-form-item>
            </el-form>
        </div>

        <script type='module'>
            import * as $util from '/lib/hc-util.js'
            window.$util = $util;
            import * as $rest from '/lib/hc-rest-service.js'
            window.$rest = $rest;
            
            function initvm(authdata, projectTree)
            {
                let currentRole = authdata.roleList.length>0?authdata.roleList[0]:{};
                // console.log('*rulePermList,funcPermList',rulePermList,funcPermList)
                $util.$tree.createId([projectTree],'rrid');
                window.vm = new Vue({
                        el: '#app',
                        data: {
                            authdata:authdata,
                            editing:'',
                            currentRole:currentRole,
                            projectTree:[projectTree],
                            rulePermList:$config.permList.filter(it=>it.type==='rule'),
                            funcPermList:$config.permList.filter(it=>it.type==='func'),
                            permit:{},
                            permitstatus:{},
                        },
                        mounted() {
                            this.$nextTick(function(){
                                assignPerms();
                                if(this.$refs.authtable)
                                    this.$refs.authtable.toggleRowExpansion(this.$refs.authtable.tableData[0],true);
                            })
                        },
                        methods: {
                            newItem:function(){
                                let item = {
                                    id:++this.authdata.usermaxid,
                                    code:'',
                                    name:'',
                                    perms:[],
                                    };
                                 this.editing ='code-' + item.id;
                                 return item;
                            },
                            handleCellDblClick:function(row, column, cell, event)
                            {
                                console.log('handleCellDblClick',row, column, cell, event)
                               let prop = column.property + '-' + row.id
                               this.editing = prop;
                               this.$nextTick(function(){
                                   let input = this.$refs[prop]
                                   if(input)input.focus();
                               })
                            },
                            handleCurrentChange:function(now,old)
                            {
                                console.log('handleCurrentChange',now,old)
                                if(old) old.perms = obtainPerms();
                                this.currentRole = now;
                                assignPerms();
                            },
                            handleInputBlur:function(prop)
                            {
                                this.editing = null;
                            },
                            handleAppend:function(){
                                this.authdata.roleList.push(this.newItem())
                            },
                            handleInsert:function(index){
                                this.authdata.roleList.splice(index,0,this.newItem())
                            },
                            handleDelete:function(index){
                                this.authdata.roleList.splice(index,1)
                            },
                            handleSave:function(){
                                let self = this;
                                self.currentRole.perms = obtainPerms();
                                $rest.postdata('/admin/save',self.authdata,function(authdata)
                                    {
                                         self.authdata = authdata;
                                         self.$message({
                                             type:'success',
                                             message:'保存成功'
                                         });
                                    }
                                );
                            },
                            handlePermitChecked:function(coder)
                            {
                                let self = this;
                                let rrid = parseInt(coder.split(':')[0]);
                                let permission = coder.split(':')[1];
                                let route = $util.$tree.routeOf(this.projectTree,rrid,'rrid');
                                let node = route[route.length-1];
                                let checked = this.permit[coder];
                                
                                self.$set(self.permitstatus,coder,false)
                                $util.$tree.traverse(node.list,function(it){
                                    let coder = it.rrid +':' + permission
                                    self.$set(self.permitstatus,coder,false)
                                    self.$set(self.permit,coder,checked)
                                });
                                for(let i = 0 ; i < route.length - 1; i++)
                                {
                                    self.$set(self.permitstatus,route[i].rrid + ':' + permission,true)
                                }
                            },
                            handleFuncPermitChecked:function(coder)
                            {
                                let self = this;
                                let checked = this.permit[coder];
                                self.$set(self.permitstatus,'@func:*',coder!=='@func:*')
                                if(coder==='@func:*')
                                {
                                    this.funcPermList.forEach(it=>
                                        self.$set(self.permit,'@func:'+it.code,checked)
                                    )
                                }
                            },
                        },
                    });
            };
            
            $rest.check$configOrLoad(function(){
                $rest.getdata('/admin/load',function(authdata){
                    $rest.getdata('/admin/projectTree',function(projectTree){
                        initvm(authdata,projectTree);
                    });
                });
            })
            
            window.obtainPerms =function()
            {
                let permit = vm.permit;
                let permitstatus = vm.permitstatus;
                let perms = [];
                vm.rulePermList.forEach(
                    it=>{
                        _obtainPerms(vm.projectTree,it.code);
                    }
                );
                
                if(permitstatus['@func:*'])
                {
                    vm.funcPermList.forEach(
                    it=>{
                        if(permit['@func:'+it.code]) perms.push('@func:'+it.code)
                        }
                    );
                    
                }else if(permit['@func:*']) perms.push('@func:*');
                
                return perms;
                
                function _obtainPerms(lst,permission)
                {
                    if(!lst) return;
                    for(let i=0;i < lst.length;i ++)
                    {
                        let node = lst[i];
                        let coder = node.rrid + ':' + permission;
                        if (permitstatus[coder]) 
                        {
                            _obtainPerms(node.list,permission);
                        }else if(permit[coder]){
                            let rpath = $util.rpath(node.rpath);
                            let p = rpath.rproject() +":" + permission + ":" + rpath.rpathInProject();
                            perms.push(p);
                        };
                    };
                };
            };
            
            window.assignPerms = function()
            {
                let role = vm.currentRole;
                let perms = role.perms;
                for(let p in vm.permit)vm.permit[p] = false;
                for(let p in vm.permitstatus)vm.permitstatus[p] = false;
                
                for(let i = 0;i<perms.length;i++)
                {
                    let segs = perms[i].split(":");
                    
                    if(segs[0]==='@func'){
                        vm.$set(vm.permit,perms[i],true);
                        vm.handleFuncPermitChecked(perms[i]);
                        continue;
                    };
                    
                    let rpath = segs[0] +'/' + segs[2];
                    let node = $util.$tree.find(vm.projectTree, rpath, 'rpath');
                    // console.log(segs,rpath,node);
                    let permissions = segs[1]==='*' ? vm.rulePermList.map(it=>it.code): [segs[1]];
                    permissions.forEach(it=>
                        {
                            let coder = node.rrid +':' + it;
                            vm.$set(vm.permit,coder,true);
                            vm.handlePermitChecked(coder);
                        }
                    )
                };
            };
        </script>
    </body>
</html>
